﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace Insteon.Messages
{


    internal abstract class Message
    {
        internal readonly IMCommand IMCommand;
        internal bool Matched = false;
        internal DateTime ReceivedTime;

        protected byte[] buffer;
        internal readonly UInt64 Number;
        internal byte[] Buffer
        {
            get
            {
                return buffer;
            }
        }


        internal Message(byte[] buffer, int Length, UInt64 Number)
        {
            if (Length < 2)
            {
                throw new Exception("message to short");
            }
            IMCommand = new IMCommand(buffer[1]);
            this.buffer = new byte[Length];
            Array.Copy(buffer, this.buffer, Length);
            this.Number = Number;
            ReceivedTime = DateTime.Now;
        }

        //note all classes that inherit from message should implement a static check function as follows.
        //it my pattern, however, I really really wish I could enforce this here in this abstract class.

        //internal static bool Check(byte[] buffer, UInt16 length)

        public override string ToString()
        {
            return PrintCommonMessage(ReceivedTime, Number, this, null, null, null, 0, 0, null);
        }

        private string BufferString()
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte byt in buffer)
            {
                sb.Append(string.Format("{0:x2} ", byt));
            }
            return sb.ToString();
        }

        internal static String PrintCommonMessage(DateTime Time, UInt64 Number, Message Message, InsteonAddress To, InsteonAddress From, Flags Flags, byte Command1, byte Command2, ResponseStatus Status)
        {
            return string.Format("{0}  {1:0000} {2,-20} (to:{3,-8}) (fr:{4,-8}) ({5}) (c1:{6,2:x} c2:{7,2:x}) {8,-3} : {9}", Time.ToString("HHmmss.fff"), Number, Message.GetType().Name, To, From, Flags, Command1, Command2, Status, Message.BufferString());
        }

        internal virtual void RouteToDevice(InsteonInterface Interface)
        {

        }

    }
}
